/*!
 * \file MD5.h
 * \brief C++ implementation of MD5 Message-Digest Algorithm as describe in
 *   RFC1321.
 *
 * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu> and heavily modified
 *   for GnuPG by <werner.koch@guug.de> and modified for the need of FPM 
 *   Blowfish Plugin.
 *
 * \author Frederic RUAUDEL <grumz@users.sf.net>
 *
 * $Revision: 1.1 $
 * $Date: 2003/03/07 10:54:38 $
 *
 * \b FPMBlowfishPlugin
 * Copyleft (c) 2003 Frederic RUAUDEL, all rights reversed
 *
 * Copyleft (C) 1995, 1996, 1998, 1999 Free Software Foundation, Inc.
 *
 * This program is free software which I release under the GNU General Public
 * License. You may redistribute and/or modify this program under the terms
 * of that license as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.  Version 2 is in the
 * COPYING file in the top level directory of this distribution.
 *
 * To get a copy of the GNU General Public License, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 **/

#ifndef MD5_H
#define MD5_H

/* Test values:
 * ""                  D4 1D 8C D9 8F 00 B2 04  E9 80 09 98 EC F8 42 7E
 * "a"                 0C C1 75 B9 C0 F1 B6 A8  31 C3 99 E2 69 77 26 61
 * "abc                90 01 50 98 3C D2 4F B0  D6 96 3F 7D 28 E1 7F 72
 * "message digest"    F9 6B 69 7D 7C B7 93 8D  52 5A 2F 31 AA F1 61 D0
 */

#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned int u32;
typedef unsigned char byte;

/****************
 * Rotate a 32 bit integer by n bytes
 */
#if defined(__GNUC__) && defined(__i386__)
static inline u32 rol( u32 x, int n)
{
	__asm__("roll %%cl,%0"
		:"=r" (x)
		:"0" (x),"c" (n));
	return x;
}
#else
  #define rol(x,n) ( ((x) << (n)) | ((x) >> (32-(n))) )
#endif

/* These are the four functions used in the four steps of the MD5 algorithm
   and defined in the RFC 1321.  The first function is a little bit optimized
   (as found in Colin Plumbs public domain implementation).  */
/* #define FF(b, c, d) ((b & c) | (~b & d)) */
#define FF(b, c, d) (d ^ (b & (c ^ d)))
#define FG(b, c, d) FF (d, b, c)
#define FH(b, c, d) (b ^ c ^ d)
#define FI(b, c, d) (c ^ (b | ~d))

using namespace std;

class MD5
{
	public:
		MD5 ();
		~MD5 ();

		byte* hash (byte *buf, size_t nbytes);
		void print (byte* key, size_t nbytes, byte* hash);

	private:
		void init (void);
		void transform (byte* data);
		void write (byte *inbuf, size_t inlen);
		void final (void);
		byte* read (void);

		u32 A,B,C,D;	  /* chaining variables */
		u32  nblocks;
		byte buf[64];
		int  count;
};

#endif /* MD5_H */
